package top.waikin.mooc.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import top.waikin.mooc.admin.service.AdminCacheService;
import top.waikin.mooc.admin.service.AdminRoleRelationService;
import top.waikin.mooc.admin.service.RolePermissionRelationService;
import top.waikin.mooc.common.exception.CacheException;
import top.waikin.mooc.common.service.RedisService;
import top.waikin.mooc.entity.Admin;
import top.waikin.mooc.entity.AdminRoleRelation;
import top.waikin.mooc.entity.Permission;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class AdminCacheServiceImpl implements AdminCacheService {
    @Autowired
    RedisService redisService;

    @Autowired
    AdminRoleRelationService adminRoleRelationService;

    @Autowired
    RolePermissionRelationService rolePermissionRelationService;

    @Value("${redis.database}")
    private String REDIS_DATABASE;
    @Value("${redis.expire.common}")
    private Long REDIS_EXPIRE;
    @Value("${redis.expire.authCode}")
    private Long REDIS_EXPIRE_AUTH_CODE;
    @Value("${redis.key.admin}")
    private String REDIS_KEY_ADMIN;
    @Value("${redis.key.authCode}")
    private String REDIS_KEY_AUTH_CODE;

    @Value("${redis.key.permissionList}")
    private String REDIS_KEY_PERMISSION_LIST;

    @Override
    public void saveAdmin(Admin Admin) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_ADMIN + ":" + Admin.getTelephone();
        redisService.set(key, Admin, REDIS_EXPIRE);
    }

    @Override
    public void deleteAdmin(String telephone) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_ADMIN + ":" + telephone;
        redisService.del(key);
    }

    @Override
    public Admin getAdmin(String telephone) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_ADMIN + ":" + telephone;
        return (Admin) redisService.get(key);
    }

    @CacheException
    @Override
    public void saveAuthCode(String telephone, String authCode) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_AUTH_CODE + ":" + telephone;
        redisService.set(key, authCode, REDIS_EXPIRE_AUTH_CODE);
    }

    @CacheException
    @Override
    public String getAuthCode(String telephone) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_AUTH_CODE + ":" + telephone;
        return (String) redisService.get(key);
    }

    @Override
    public void savePermissionList(Integer adminId, List<Permission> permissionList) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_PERMISSION_LIST + ":" + adminId;
        redisService.set(key, permissionList, REDIS_EXPIRE);
    }

    @Override
    public void deletePermissionList(Integer adminId) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_PERMISSION_LIST + ":" + adminId;
        redisService.del(key);
    }

    @Override
    public List<Permission> getPermissionList(Integer adminId) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_PERMISSION_LIST + ":" + adminId;
        return (List<Permission>) redisService.get(key);
    }

    @Override
    public void deletePermissionListByRole(Integer roleId) {
        Wrapper<AdminRoleRelation> wrapper = new LambdaQueryWrapper<AdminRoleRelation>().eq(AdminRoleRelation::getRoleId, roleId);
        List<AdminRoleRelation> adminRoleRelations = adminRoleRelationService.list(wrapper);
        String key_prefix = REDIS_DATABASE + ":" + REDIS_KEY_PERMISSION_LIST + ":";
        List<String> keys = adminRoleRelations.stream().map(adminRoleRelation -> key_prefix + adminRoleRelation.getAdminId()).collect(Collectors.toList());
        redisService.del(keys);
    }

    @Override
    public void deletePermissionListByPermission(Integer permissionId) {
        List<Integer> adminIdList = rolePermissionRelationService.getAdminIdListByPermissionId(permissionId);
        String key_prefix = REDIS_DATABASE + ":" + REDIS_KEY_PERMISSION_LIST + ":";
        List<String> keys = adminIdList.stream().map(integer -> key_prefix + integer).collect(Collectors.toList());
        redisService.del(keys);
    }
}
